home *** CD-ROM | disk | FTP | other *** search
- /*
-
- bfile.cpp
- Btrieve class for Borland C++
- 09/06/91
-
- Douglas J. Reilly
- Access Microsystems Inc.
- 404 Midstreams Road
- Brick, New Jersey 08724
- (908) 892-2683
- CompuServe 74040,607
-
- Comments? Questions? Suggestions?
- Have a paying C/C++ programming job you need done?
- Give me a call.
-
- Released into the public domain. Do with it as you see fit, but
- if you do anything really neat with it, let me know...
-
- 11/11/91 DR Lots of little changes to better handle variable length
- records.
- */
- #define EOS '\0'
-
- #include "stdio.h"
- #include "stdlib.h"
- #include "mem.h"
- #include "string.h"
- #include "ctype.h"
- #include "bfile.h" // class description for bfile
-
- class bfile;
- // #define this, link it with the TURBCBTR module and see an example.
- // USAGE: bfile /f:filename.ext /k:key_num
- //#define TEST
- #ifdef TEST
- main(int argc,char *argv[])
- {
- char temp[100];
- int ret;
- int loop;
- static char file[70]={""};
- int key=-1;
- temp[0]='\0';
-
- memset(temp,'\0',100);
-
- for ( loop=1 ; loop<argc ; loop++ )
- {
- if ( argv[loop][0]=='/' )
- {
- switch ( (toupper(argv[loop][1])) )
- {
- case 'K':
- key=atoi(&argv[loop][3]);
- break;
- case 'F':
- strcpy(file,&argv[loop][3]);
- break;
- }
- }
- }
-
-
- bfile sum(file,4096,"(C)SMI",0);
- sum.set_key_num(key);
-
- printf("\nsum.get_rec(temp,B_GET_LO)=%d data=%30.30s temp=|%s|",
- sum.get_rec(temp,B_GET_LO),
- sum.get_data(),temp);
- do {
- printf("\nsum.get_rec(temp,B_GET_NEXT)=%d data=%30.30s temp=|%s|",
- ret=sum.get_rec(temp,B_GET_NEXT),
- sum.get_data(),temp);
- } while ( ret==0 );
- }
- #endif
-
- bfile::bfile(char *name,int len,char *towner,int newmode)
- {
- int tlen=0;
-
- key_num=0;
- opened=0;
- data=0;
- strcpy(fname,name);
- mode=newmode;
- if ( towner!=0 )
- {
- strcpy(data,towner);
- strcpy(owner,towner);
- tlen=(strlen(towner))+1;
- }
- else
- {
- tlen=len;
- }
- status=BTRV(B_OPEN,pos_blk,data,&tlen,fname,mode);
- if ( status && status!=BERR_REC_BUF_ERR )
- {
- // printf("\nOpen failed for %s-status %d",fname,status);
- }
- else
- {
- opened=1;
- // DECLARATION!
- struct FIL_SPEC fil_spec;
- get_bstat(&fil_spec);
- file_flag=fil_spec.FILE_FLAG;
- if ( len )
- {
- rec_len=len;
- // get the fixed len from the FIL_SPEC
- fixed_len=fil_spec.REC_LEN;
- }
- else
- {
- if ( file_flag&1 ) // variable len?
- {
- rec_len=5000; // assume 5000, what the heck...
- }
- else
- {
- rec_len=fil_spec.REC_LEN;
- }
- fixed_len=fil_spec.REC_LEN;
- }
- last_rec_len=0;
- num_keys=fil_spec.NDX_CNT;
- data=new char[rec_len];
- if ( data==0 )
- {
- close();
- opened=0;
- status=BERR_MEM_ALLOC;
- }
- }
- }
- bfile::~bfile()
- {
- if ( !(opened) )
- {
- return;
- }
- else
- {
- status=BTRV(B_CLOSE,pos_blk,data,&rec_len,fname,mode);
- delete data;
- data=0;
- opened=0;
- }
- }
-
- int bfile::close()
- {
- if ( data!=0 )
- {
- delete data;
- data=0;
- }
- if ( !(opened) )
- {
- return 0;
- }
- else
- {
- status=BTRV(B_CLOSE,pos_blk,data,&rec_len,fname,mode);
- opened=0;
- return 1;
- }
- }
-
- int bfile::open(int newmode)
- {
- if ( opened )
- {
- return 0;
- }
- if ( newmode!=-99 )
- {
- mode=newmode;
- }
- opened=0;
- data=new char[rec_len];
- if ( data==0 )
- {
- // printf("\nOpen failed for %s-No memory",fname);
- status=BERR_MEM_ALLOC;
- }
- if ( owner!=0 )
- {
- strcpy(data,owner);
- }
- status=BTRV(B_OPEN,pos_blk,data,&rec_len,fname,mode);
- if ( status )
- {
- delete data;
- data=0;
- }
- else
- {
- opened=1;
- }
- return(status);
- }
-
- int bfile::get_rec(char *keystr,int op)
- {
- int tlen;
- if ( !(opened) || data==0 )
- {
- return(BERR_NO_OPEN); // btrieve status for not opened...
- }
- tlen=rec_len;
- memset(data,EOS,rec_len);
- status=BTRV(op,pos_blk,data,&tlen,keystr,key_num);
- last_rec_len=tlen;
- return(status);
- }
-
- int bfile::put_rec(char *keystr,int tlen)
- {
- char *tdata;
- char tkey[128];
- int stat;
-
- tdata=new char[rec_len];
- memcpy(tdata,data,rec_len);
- memcpy(tkey,keystr,128);
-
- // This is how I save btrieve data. I understand that there is some
- // potential for problem with this, since by always re-establishing
- // positioning, I won't know if someone changed the data since I last
- // got the rec, but in things I have done, I lock the records first
- // anyway...
-
- if ( (stat=get_rec(keystr))!=0 )
- {
- if ( stat!=BERR_REC_NOT_FOUND && stat!=BERR_EOF )
- {
- delete tdata;
- return(stat);
- }
- // new record?
- if ( tlen==0 )
- {
- tlen=rec_len;
- }
- status=BTRV(B_INSERT,pos_blk,tdata,&tlen,tkey,key_num);
- last_rec_len=tlen;
- }
- else
- {
- if ( tlen==0 )
- {
- tlen=rec_len;
- }
- status=BTRV(B_UPDATE,pos_blk,tdata,&tlen,tkey,key_num);
- last_rec_len=tlen;
- }
- if ( !(status) )
- {
- memcpy(data,tdata,rec_len);
- strcpy(keystr,tkey);
- }
- delete tdata;
- return status;
- }
-
- int bfile::del_rec(char *keystr)
- {
- char *tdata;
- char tkey[128];
- int stat;
-
- // use tdata so as not to destroy infor in data...
- tdata=new char[rec_len];
- memcpy(tdata,data,rec_len);
- memcpy(tkey,keystr,128);
- if ( (stat=get_rec(keystr))!=0 )
- {
- delete tdata;
- return(stat);
- }
- else
- {
- status=BTRV(B_DELETE,pos_blk,tdata,&rec_len,tkey,key_num);
- }
- if ( !(status) )
- {
- memcpy(data,tdata,rec_len);
- strcpy(keystr,tkey);
- }
- delete tdata;
- return status;
- }
-
- void bfile::get_bstat(struct FIL_SPEC *fil_spec)
- {
- int tlen=(sizeof(struct FIL_SPEC));
- char temp[60]; // S/B big enough to hold extension file name if
- // name is returned.
- status=BTRV(B_STAT,pos_blk,(char *)fil_spec,&tlen,temp,mode);
- if ( status==22 )
- {
- status=0;
- }
- }
- int bfile::set_pos(char *buf,char *keystr)
- {
- int tlen=rec_len;
- char temp[256];
- memcpy(data,buf,4);
- status=BTRV(B_GET_DIRECT,pos_blk,data,&tlen,temp,key_num);
- if ( keystr )
- {
- strcpy(keystr,temp);
- }
- return(status);
- }
-
- int bfile::clone_file(char *destfname,int overwrite)
- {
- struct FIL_SPEC fil_spec;
- int tlen=(sizeof(struct FIL_SPEC));
- char new_pos[128];
- int newstat;
- int tkey;
-
- if ( overwrite )
- {
- tkey=0;
- }
- else
- {
- tkey=-1;
- }
- get_bstat(&fil_spec);
- if ( !(get_status()) )
- {
- newstat=BTRV(B_CREATE,new_pos,(char *)&fil_spec,&tlen,destfname,tkey);
- }
- else
- {
- newstat=get_status();
- }
- return(newstat);
- }
-
- int bfile::get_key_len(int tkey_num)
- {
- struct FIL_SPEC fil_spec;
- int key_loop;
- int key_len=0;
- if ( tkey_num==-1 )
- {
- tkey_num=key_num;
- }
- get_bstat(&fil_spec);
- int loop;
- for ( loop=0,key_loop=0 ; key_loop<tkey_num && loop<24 ; loop++ )
- {
- if ( !(fil_spec.KEY_BUF[loop].KEY_FLAG&16) ) // last seg?
- {
- key_loop++;
- }
- }
- while ( loop<24 &&
- (fil_spec.KEY_BUF[loop].KEY_FLAG&16) ) // another seg?
- {
- key_len+=fil_spec.KEY_BUF[loop].KEY_LEN;
- loop++;
- }
- key_len+=fil_spec.KEY_BUF[loop].KEY_LEN;
- return(key_len);
- }